package org.test.client.ui.component.panel;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

/**
 * 可以将一个面板锁定
 * @author Guodeqi
 *
 */
public class FadeAndBusyPanelWrapper extends JLayeredPane{
	private Container c = null;
	private BusyPanel busyPanel = null;
	private boolean busy = false;
	
	private Integer panelLayerIndex = new Integer(1);
	private Integer busyLayerIndex = new Integer(100);
	public int w = 0;
	public int h = 0;
	
	public FadeAndBusyPanelWrapper(Container c){
		this.c = c;

		Dimension d1 = c.getPreferredSize();
		Dimension d2 = c.getSize();
		w = d1.width > d2.width? d1.width : d2.width;
		h = d1.height > d2.height? d1.height : d2.height;
		
		this.add(c,panelLayerIndex);
		c.setBounds(0, 0, w, h);
		this.setSize(w, h);
		this.setPreferredSize(new Dimension(w,h));
		
		busyPanel = new BusyPanel(this,c);
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		w = this.getWidth();
		h= this.getHeight();
		c.setBounds(0, 0, w,h);
		super.paintComponent(g);
	}
	
	public void  setBusy(boolean busy){
		if(this.busy == busy){
			return ;
		}
		this.busy = busy;
		if(busy){
			this.add(busyPanel,busyLayerIndex);
			new Thread(busyPanel).start();
		}else{
			this.remove(busyPanel);
			busyPanel.runFlag = false;
			this.remove(busyPanel);
			this.repaint();
		}
	}
	
	public static void main(String[] args) throws Exception {
		
		JPanel testPanel = new JPanel();
		testPanel.setBackground(Color.red);
		
		testPanel.add(new JButton("aaaa"));
		FadeAndBusyPanelWrapper wrapper = new FadeAndBusyPanelWrapper(testPanel);
		
		JFrame fff = new JFrame();
		Container contentPane = fff.getContentPane();
		contentPane.add(wrapper);
		fff.setDefaultCloseOperation(fff.EXIT_ON_CLOSE);
		fff.setSize(500, 300);
		fff.setLocationRelativeTo(null);
		fff.setVisible(true);
		
		Thread.sleep(2000);
		wrapper.setBusy(true);
		Thread.sleep(2000);
		wrapper.setBusy(false);
	}
	
}

class BusyPanel extends JPanel implements Runnable{
	Container c;
	public boolean runFlag = true;
	FadeAndBusyPanelWrapper wrapper;
	public BusyPanel(FadeAndBusyPanelWrapper wrapper, Container c) {
		this.c = c;
		this.wrapper = wrapper;
		this.setOpaque(false);
		this.addMouseListener(new MouseAdapter(){});
		this.setBounds(0, 0, wrapper.w, wrapper.h);
	}
	
	private int mAngle = 0;
	private float fade = 0.0f;
	@Override
	protected void paintComponent(Graphics g) {
		this.setBounds(0, 0, wrapper.w, wrapper.h);
		super.paintComponent(g);
		
		//画indicator
	    int w = this.getWidth();
	    int h = this.getHeight();
		Graphics2D g2 = (Graphics2D)g.create();
		 
	    // Gray it out.
	    Composite urComposite = g2.getComposite();
	    g2.setComposite(AlphaComposite.getInstance(
	        AlphaComposite.SRC_OVER, .5f * fade));
	    g2.fillRect(0, 0, w, h);
	    g2.setComposite(urComposite);
	 
	    // Paint the wait indicator.
	    int s = Math.min(w, h) / 5;
	    int cx = w / 2;
	    int cy = h / 2;
	    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
	        RenderingHints.VALUE_ANTIALIAS_ON);
	    g2.setStroke(
	        new BasicStroke(s / 4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
	    g2.setPaint(Color.white);
	    g2.rotate(Math.PI * mAngle / 180, cx, cy);
	    
	    for (int i = 0; i < 12; i++) {
	      float scale = (11.0f - (float)i) / 11.0f;
	      g2.drawLine(cx + s, cy, cx + s * 2, cy);
	      g2.rotate(-Math.PI / 6, cx, cy);
	      g2.setComposite(AlphaComposite.getInstance(
	          AlphaComposite.SRC_OVER, scale * fade));
	    }
	 
	    g2.dispose();
	}


	@Override
	public void run() {
		try {
			int count = 0;
			while(runFlag){
				Thread.sleep(100);
				if(fade < 0.5){
					fade = fade + 0.1f;
				}
				mAngle = (mAngle+30)%360;
				this.repaint();
			}
			
			while(fade > 0.1){
				fade = fade - 0.1f;
				this.repaint();
				Thread.sleep(100);
			}
			runFlag = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}
